//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension OpsWorksCM {
    // MARK: Enums

    public enum BackupStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case deleting = "DELETING"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case ok = "OK"
        public var description: String { return self.rawValue }
    }

    public enum BackupType: String, CustomStringConvertible, Codable, _SotoSendable {
        case automated = "AUTOMATED"
        case manual = "MANUAL"
        public var description: String { return self.rawValue }
    }

    public enum MaintenanceStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum NodeAssociationStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum ServerStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case backingUp = "BACKING_UP"
        case connectionLost = "CONNECTION_LOST"
        case creating = "CREATING"
        case deleting = "DELETING"
        case failed = "FAILED"
        case healthy = "HEALTHY"
        case modifying = "MODIFYING"
        case restoring = "RESTORING"
        case running = "RUNNING"
        case setup = "SETUP"
        case terminated = "TERMINATED"
        case underMaintenance = "UNDER_MAINTENANCE"
        case unhealthy = "UNHEALTHY"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AccountAttribute: AWSDecodableShape {
        ///  The maximum allowed value.
        public let maximum: Int?
        ///  The attribute name. The following are supported attribute names.     ServerLimit: The number of current servers/maximum number of servers allowed. By default, you can have a maximum of 10 servers.     ManualBackupLimit: The number of current manual backups/maximum number of backups allowed. By default, you can have a maximum  of 50 manual backups saved.
        public let name: String?
        ///  The current usage, such as the current number of servers that are associated with the account.
        public let used: Int?

        public init(maximum: Int? = nil, name: String? = nil, used: Int? = nil) {
            self.maximum = maximum
            self.name = name
            self.used = used
        }

        private enum CodingKeys: String, CodingKey {
            case maximum = "Maximum"
            case name = "Name"
            case used = "Used"
        }
    }

    public struct AssociateNodeRequest: AWSEncodableShape {
        /// Engine attributes used for associating the node.   Attributes accepted in a AssociateNode request for Chef     CHEF_ORGANIZATION: The Chef organization with which the node is associated. By default only one organization named default can exist.     CHEF_NODE_PUBLIC_KEY: A PEM-formatted public key. This key is required for the chef-client agent to access the Chef API.     Attributes accepted in a AssociateNode request for Puppet     PUPPET_NODE_CSR: A PEM-formatted certificate-signing request (CSR) that is created by the node.
        public let engineAttributes: [EngineAttribute]
        /// The name of the node.
        public let nodeName: String
        /// The name of the server with which to associate the node.
        public let serverName: String

        public init(engineAttributes: [EngineAttribute], nodeName: String, serverName: String) {
            self.engineAttributes = engineAttributes
            self.nodeName = nodeName
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.engineAttributes.forEach {
                try $0.validate(name: "\(name).engineAttributes[]")
            }
            try self.validate(self.nodeName, name: "nodeName", parent: name, max: 10000)
            try self.validate(self.nodeName, name: "nodeName", parent: name, pattern: "^[\\-\\p{Alnum}_:.]+$")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case engineAttributes = "EngineAttributes"
            case nodeName = "NodeName"
            case serverName = "ServerName"
        }
    }

    public struct AssociateNodeResponse: AWSDecodableShape {
        /// Contains a token which can be passed to the DescribeNodeAssociationStatus API call to get the status of the association request.
        public let nodeAssociationStatusToken: String?

        public init(nodeAssociationStatusToken: String? = nil) {
            self.nodeAssociationStatusToken = nodeAssociationStatusToken
        }

        private enum CodingKeys: String, CodingKey {
            case nodeAssociationStatusToken = "NodeAssociationStatusToken"
        }
    }

    public struct Backup: AWSDecodableShape {
        /// The ARN of the backup.
        public let backupArn: String?
        ///  The generated ID of the backup. Example: myServerName-yyyyMMddHHmmssSSS
        public let backupId: String?
        ///  The backup type. Valid values are automated or manual.
        public let backupType: BackupType?
        ///  The time stamp when the backup was created in the database. Example: 2016-07-29T13:38:47.520Z
        public let createdAt: Date?
        ///  A user-provided description for a manual backup. This field is empty for automated backups.
        public let description: String?
        ///  The engine type that is obtained from the server when the backup is created.
        public let engine: String?
        ///  The engine model that is obtained from the server when the backup is created.
        public let engineModel: String?
        ///  The engine version that is obtained from the server when the backup is created.
        public let engineVersion: String?
        ///  The EC2 instance profile ARN that is obtained from the server when the backup is created. Because this value is stored, you are not required to provide the InstanceProfileArn again if you restore a backup.
        public let instanceProfileArn: String?
        ///  The instance type that is obtained from the server when the backup is created.
        public let instanceType: String?
        ///  The key pair that is obtained from the server when the backup is created.
        public let keyPair: String?
        ///  The preferred backup period that is obtained from the server when the backup is created.
        public let preferredBackupWindow: String?
        ///  The preferred maintenance period that is obtained from the server when the backup is created.
        public let preferredMaintenanceWindow: String?
        ///  This field is deprecated and is no longer used.
        public let s3DataSize: Int?
        ///  This field is deprecated and is no longer used.
        public let s3DataUrl: String?
        ///  The Amazon S3 URL of the backup's log file.
        public let s3LogUrl: String?
        ///  The security group IDs that are obtained from the server when the backup is created.
        public let securityGroupIds: [String]?
        ///  The name of the server from which the backup was made.
        public let serverName: String?
        ///  The service role ARN that is obtained from the server when the backup is created.
        public let serviceRoleArn: String?
        /// The status of a backup while in progress.
        public let status: BackupStatus?
        ///  An informational message about backup status.
        public let statusDescription: String?
        ///  The subnet IDs that are obtained from the server when the backup is created.
        public let subnetIds: [String]?
        ///  The version of AWS OpsWorks CM-specific tools that is obtained from the server when the backup is created.
        public let toolsVersion: String?
        ///  The IAM user ARN of the requester for manual backups. This field is empty for automated backups.
        public let userArn: String?

        public init(backupArn: String? = nil, backupId: String? = nil, backupType: BackupType? = nil, createdAt: Date? = nil, description: String? = nil, engine: String? = nil, engineModel: String? = nil, engineVersion: String? = nil, instanceProfileArn: String? = nil, instanceType: String? = nil, keyPair: String? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, s3LogUrl: String? = nil, securityGroupIds: [String]? = nil, serverName: String? = nil, serviceRoleArn: String? = nil, status: BackupStatus? = nil, statusDescription: String? = nil, subnetIds: [String]? = nil, toolsVersion: String? = nil, userArn: String? = nil) {
            self.backupArn = backupArn
            self.backupId = backupId
            self.backupType = backupType
            self.createdAt = createdAt
            self.description = description
            self.engine = engine
            self.engineModel = engineModel
            self.engineVersion = engineVersion
            self.instanceProfileArn = instanceProfileArn
            self.instanceType = instanceType
            self.keyPair = keyPair
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.s3DataSize = nil
            self.s3DataUrl = nil
            self.s3LogUrl = s3LogUrl
            self.securityGroupIds = securityGroupIds
            self.serverName = serverName
            self.serviceRoleArn = serviceRoleArn
            self.status = status
            self.statusDescription = statusDescription
            self.subnetIds = subnetIds
            self.toolsVersion = toolsVersion
            self.userArn = userArn
        }

        @available(*, deprecated, message: "Members s3DataSize, s3DataUrl have been deprecated")
        public init(backupArn: String? = nil, backupId: String? = nil, backupType: BackupType? = nil, createdAt: Date? = nil, description: String? = nil, engine: String? = nil, engineModel: String? = nil, engineVersion: String? = nil, instanceProfileArn: String? = nil, instanceType: String? = nil, keyPair: String? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, s3DataSize: Int? = nil, s3DataUrl: String? = nil, s3LogUrl: String? = nil, securityGroupIds: [String]? = nil, serverName: String? = nil, serviceRoleArn: String? = nil, status: BackupStatus? = nil, statusDescription: String? = nil, subnetIds: [String]? = nil, toolsVersion: String? = nil, userArn: String? = nil) {
            self.backupArn = backupArn
            self.backupId = backupId
            self.backupType = backupType
            self.createdAt = createdAt
            self.description = description
            self.engine = engine
            self.engineModel = engineModel
            self.engineVersion = engineVersion
            self.instanceProfileArn = instanceProfileArn
            self.instanceType = instanceType
            self.keyPair = keyPair
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.s3DataSize = s3DataSize
            self.s3DataUrl = s3DataUrl
            self.s3LogUrl = s3LogUrl
            self.securityGroupIds = securityGroupIds
            self.serverName = serverName
            self.serviceRoleArn = serviceRoleArn
            self.status = status
            self.statusDescription = statusDescription
            self.subnetIds = subnetIds
            self.toolsVersion = toolsVersion
            self.userArn = userArn
        }

        private enum CodingKeys: String, CodingKey {
            case backupArn = "BackupArn"
            case backupId = "BackupId"
            case backupType = "BackupType"
            case createdAt = "CreatedAt"
            case description = "Description"
            case engine = "Engine"
            case engineModel = "EngineModel"
            case engineVersion = "EngineVersion"
            case instanceProfileArn = "InstanceProfileArn"
            case instanceType = "InstanceType"
            case keyPair = "KeyPair"
            case preferredBackupWindow = "PreferredBackupWindow"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case s3DataSize = "S3DataSize"
            case s3DataUrl = "S3DataUrl"
            case s3LogUrl = "S3LogUrl"
            case securityGroupIds = "SecurityGroupIds"
            case serverName = "ServerName"
            case serviceRoleArn = "ServiceRoleArn"
            case status = "Status"
            case statusDescription = "StatusDescription"
            case subnetIds = "SubnetIds"
            case toolsVersion = "ToolsVersion"
            case userArn = "UserArn"
        }
    }

    public struct CreateBackupRequest: AWSEncodableShape {
        ///  A user-defined description of the backup.
        public let description: String?
        /// The name of the server that you want to back up.
        public let serverName: String
        /// A map that contains tag keys and tag values to attach to an AWS OpsWorks-CM server backup.   The key cannot be empty.   The key can be a maximum of 127 characters, and can contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /    The value can be a maximum 255 characters, and contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /    Leading and trailing white spaces are trimmed from both the key and value.   A maximum of 50 user-applied tags is allowed for tag-supported AWS OpsWorks-CM resources.
        public let tags: [Tag]?

        public init(description: String? = nil, serverName: String, tags: [Tag]? = nil) {
            self.description = description
            self.serverName = serverName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 10000)
            try self.validate(self.description, name: "description", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case serverName = "ServerName"
            case tags = "Tags"
        }
    }

    public struct CreateBackupResponse: AWSDecodableShape {
        /// Backup created by request.
        public let backup: Backup?

        public init(backup: Backup? = nil) {
            self.backup = backup
        }

        private enum CodingKeys: String, CodingKey {
            case backup = "Backup"
        }
    }

    public struct CreateServerRequest: AWSEncodableShape {
        ///  Associate a public IP address with a server that you are launching. Valid values are true or false. The default value is true.
        public let associatePublicIpAddress: Bool?
        ///  If you specify this field, AWS OpsWorks CM creates the server by using the backup represented by BackupId.
        public let backupId: String?
        ///  The number of automated backups that you want to keep. Whenever a new backup is created, AWS OpsWorks CM deletes the oldest backups if this number is exceeded. The default value is 1.
        public let backupRetentionCount: Int?
        /// A PEM-formatted HTTPS certificate. The value can be be a single, self-signed certificate, or a certificate chain. If you specify a  custom certificate, you must also specify values for CustomDomain and CustomPrivateKey. The following are requirements for the CustomCertificate value:   You can provide either a self-signed, custom certificate, or the full certificate chain.   The certificate must be a valid X509 certificate, or a certificate chain in PEM format.   The certificate must be valid at the time of upload. A certificate can't be used before its validity period begins (the certificate's NotBefore date), or after it expires  (the certificate's NotAfter date).   The certificate’s common name or subject alternative names (SANs), if present, must match the value of CustomDomain.   The certificate must match the value of CustomPrivateKey.
        public let customCertificate: String?
        /// An optional public endpoint of a server, such as https://aws.my-company.com. To access the server, create a CNAME DNS record in your preferred DNS service that points the custom  domain to the endpoint that is generated when the server is created (the value of the CreateServer Endpoint attribute). You cannot access the server by using the  generated Endpoint value if the server is using a custom domain. If you specify a custom domain, you must also specify values for CustomCertificate  and CustomPrivateKey.
        public let customDomain: String?
        /// A private key in PEM format for connecting to the server by using HTTPS. The private key must not be encrypted; it cannot be protected by a password or passphrase.  If you specify a custom private key, you must also specify values for CustomDomain and CustomCertificate.
        public let customPrivateKey: String?
        ///  Enable or disable scheduled backups. Valid values are true or false. The default value is true.
        public let disableAutomatedBackup: Bool?
        ///  The configuration management engine to use. Valid values include ChefAutomate and Puppet.
        public let engine: String
        /// Optional engine attributes on a specified server.   Attributes accepted in a Chef createServer request:     CHEF_AUTOMATE_PIVOTAL_KEY: A base64-encoded RSA public key. The corresponding private key is required to access the Chef API. When no CHEF_AUTOMATE_PIVOTAL_KEY is set, a private key is generated and returned in the response.     CHEF_AUTOMATE_ADMIN_PASSWORD: The password for the administrative user in the Chef Automate web-based dashboard. The password length is a minimum of eight characters, and a maximum of 32. The password can contain letters, numbers, and special characters (!/@#$%^&+=_). The password must contain at least one lower case letter, one upper case letter, one number, and one special character. When no CHEF_AUTOMATE_ADMIN_PASSWORD is set, one is generated and returned in the response.    Attributes accepted in a Puppet createServer request:     PUPPET_ADMIN_PASSWORD: To work with the Puppet Enterprise console, a password must use ASCII characters.    PUPPET_R10K_REMOTE: The r10k remote is the URL of your control repository  (for example, ssh://git@your.git-repo.com:user/control-repo.git). Specifying an r10k remote opens TCP port 8170.    PUPPET_R10K_PRIVATE_KEY: If you are using a private Git repository, add  PUPPET_R10K_PRIVATE_KEY to specify a PEM-encoded private SSH key.
        public let engineAttributes: [EngineAttribute]?
        ///  The engine model of the server. Valid values in this release include Monolithic for Puppet and Single for Chef.
        public let engineModel: String?
        ///  The major release version of the engine that you want to use. For a Chef server, the valid value for EngineVersion  is currently 2. For a Puppet server, valid values are 2019 or 2017.
        public let engineVersion: String?
        ///  The ARN of the instance profile that your Amazon EC2 instances use. Although the AWS OpsWorks console typically creates the instance profile for you, if you are using API commands instead, run the service-role-creation.yaml AWS CloudFormation template, located at https://s3.amazonaws.com/opsworks-cm-us-east-1-prod-default-assets/misc/opsworks-cm-roles.yaml. This template creates a CloudFormation stack that includes the instance profile you need.
        public let instanceProfileArn: String
        ///  The Amazon EC2 instance type to use. For example, m5.large.
        public let instanceType: String
        ///  The Amazon EC2 key pair to set for the instance. This parameter is optional; if desired, you may specify this parameter to connect to your instances by using SSH.
        public let keyPair: String?
        ///  The start time for a one-hour period during which AWS OpsWorks CM backs up application-level data on your server if automated backups are enabled. Valid values must be specified in one of the following formats:     HH:MM for daily backups    DDD:HH:MM for weekly backups    MM must be specified as 00. The specified time is in coordinated universal time (UTC). The default value is a random, daily start time.  Example:  08:00, which represents a daily start time of 08:00 UTC.  Example:  Mon:08:00, which represents a start time of every Monday at 08:00 UTC. (8:00 a.m.)
        public let preferredBackupWindow: String?
        ///  The start time for a one-hour period each week during which AWS OpsWorks CM performs maintenance on the instance. Valid values must be specified in the following format: DDD:HH:MM. MM must be specified as 00. The specified time is in coordinated universal time (UTC). The default value is a random one-hour period on Tuesday, Wednesday, or Friday. See TimeWindowDefinition for more information.   Example: Mon:08:00, which represents a start time of every Monday at 08:00 UTC. (8:00 a.m.)
        public let preferredMaintenanceWindow: String?
        ///  A list of security group IDs to attach to the Amazon EC2 instance. If you add this parameter, the specified security groups must be within the VPC that is specified by SubnetIds.   If you do not specify this parameter, AWS OpsWorks CM creates one new security group that uses TCP ports 22 and 443, open to 0.0.0.0/0 (everyone).
        public let securityGroupIds: [String]?
        ///  The name of the server. The server name must be unique within your AWS account, within each region. Server names must start with a letter; then letters, numbers, or hyphens (-) are allowed, up to a maximum of 40 characters.
        public let serverName: String
        ///  The service role that the AWS OpsWorks CM service backend uses to work with your account. Although the AWS OpsWorks management console typically creates the service role for you, if you are using the AWS CLI or API commands, run the service-role-creation.yaml AWS CloudFormation template, located at https://s3.amazonaws.com/opsworks-cm-us-east-1-prod-default-assets/misc/opsworks-cm-roles.yaml. This template creates a CloudFormation stack that includes the service role and instance profile that you need.
        public let serviceRoleArn: String
        ///  The IDs of subnets in which to launch the server EC2 instance.   Amazon EC2-Classic customers: This field is required. All servers must run within a VPC. The VPC must have "Auto Assign Public IP" enabled.   EC2-VPC customers: This field is optional. If you do not specify subnet IDs, your EC2 instances are created in a default subnet that is selected by Amazon EC2. If you specify subnet IDs, the VPC must have "Auto Assign Public IP" enabled.  For more information about supported Amazon EC2 platforms, see Supported Platforms.
        public let subnetIds: [String]?
        /// A map that contains tag keys and tag values to attach to an AWS OpsWorks for Chef Automate or AWS OpsWorks for Puppet Enterprise server.   The key cannot be empty.   The key can be a maximum of 127 characters, and can contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : / @    The value can be a maximum 255 characters, and contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : / @    Leading and trailing white spaces are trimmed from both the key and value.   A maximum of 50 user-applied tags is allowed for any AWS OpsWorks-CM server.
        public let tags: [Tag]?

        public init(associatePublicIpAddress: Bool? = nil, backupId: String? = nil, backupRetentionCount: Int? = nil, customCertificate: String? = nil, customDomain: String? = nil, customPrivateKey: String? = nil, disableAutomatedBackup: Bool? = nil, engine: String, engineAttributes: [EngineAttribute]? = nil, engineModel: String? = nil, engineVersion: String? = nil, instanceProfileArn: String, instanceType: String, keyPair: String? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, securityGroupIds: [String]? = nil, serverName: String, serviceRoleArn: String, subnetIds: [String]? = nil, tags: [Tag]? = nil) {
            self.associatePublicIpAddress = associatePublicIpAddress
            self.backupId = backupId
            self.backupRetentionCount = backupRetentionCount
            self.customCertificate = customCertificate
            self.customDomain = customDomain
            self.customPrivateKey = customPrivateKey
            self.disableAutomatedBackup = disableAutomatedBackup
            self.engine = engine
            self.engineAttributes = engineAttributes
            self.engineModel = engineModel
            self.engineVersion = engineVersion
            self.instanceProfileArn = instanceProfileArn
            self.instanceType = instanceType
            self.keyPair = keyPair
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.securityGroupIds = securityGroupIds
            self.serverName = serverName
            self.serviceRoleArn = serviceRoleArn
            self.subnetIds = subnetIds
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.backupId, name: "backupId", parent: name, max: 79)
            try self.validate(self.backupId, name: "backupId", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-\\.\\:]*")
            try self.validate(self.backupRetentionCount, name: "backupRetentionCount", parent: name, min: 1)
            try self.validate(self.customCertificate, name: "customCertificate", parent: name, max: 2_097_152)
            try self.validate(self.customCertificate, name: "customCertificate", parent: name, pattern: "(?s)\\s*-----BEGIN CERTIFICATE-----.+-----END CERTIFICATE-----\\s*")
            try self.validate(self.customDomain, name: "customDomain", parent: name, max: 253)
            try self.validate(self.customDomain, name: "customDomain", parent: name, pattern: "^(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
            try self.validate(self.customPrivateKey, name: "customPrivateKey", parent: name, max: 4096)
            try self.validate(self.customPrivateKey, name: "customPrivateKey", parent: name, pattern: "(?ms)\\s*^-----BEGIN (?-s:.*)PRIVATE KEY-----$.*?^-----END (?-s:.*)PRIVATE KEY-----$\\s*")
            try self.validate(self.engine, name: "engine", parent: name, max: 10000)
            try self.validate(self.engine, name: "engine", parent: name, pattern: "(?s).*")
            try self.engineAttributes?.forEach {
                try $0.validate(name: "\(name).engineAttributes[]")
            }
            try self.validate(self.engineModel, name: "engineModel", parent: name, max: 10000)
            try self.validate(self.engineModel, name: "engineModel", parent: name, pattern: "(?s).*")
            try self.validate(self.engineVersion, name: "engineVersion", parent: name, max: 10000)
            try self.validate(self.engineVersion, name: "engineVersion", parent: name, pattern: "(?s).*")
            try self.validate(self.instanceProfileArn, name: "instanceProfileArn", parent: name, max: 10000)
            try self.validate(self.instanceProfileArn, name: "instanceProfileArn", parent: name, pattern: "arn:aws:iam::[0-9]{12}:instance-profile/.*")
            try self.validate(self.instanceType, name: "instanceType", parent: name, max: 10000)
            try self.validate(self.instanceType, name: "instanceType", parent: name, pattern: "(?s).*")
            try self.validate(self.keyPair, name: "keyPair", parent: name, max: 10000)
            try self.validate(self.keyPair, name: "keyPair", parent: name, pattern: ".*")
            try self.validate(self.preferredBackupWindow, name: "preferredBackupWindow", parent: name, max: 10000)
            try self.validate(self.preferredBackupWindow, name: "preferredBackupWindow", parent: name, pattern: "^((Mon|Tue|Wed|Thu|Fri|Sat|Sun):)?([0-1][0-9]|2[0-3]):[0-5][0-9]$")
            try self.validate(self.preferredMaintenanceWindow, name: "preferredMaintenanceWindow", parent: name, max: 10000)
            try self.validate(self.preferredMaintenanceWindow, name: "preferredMaintenanceWindow", parent: name, pattern: "^((Mon|Tue|Wed|Thu|Fri|Sat|Sun):)?([0-1][0-9]|2[0-3]):[0-5][0-9]$")
            try self.securityGroupIds?.forEach {
                try validate($0, name: "securityGroupIds[]", parent: name, max: 10000)
                try validate($0, name: "securityGroupIds[]", parent: name, pattern: "(?s).*")
            }
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
            try self.validate(self.serviceRoleArn, name: "serviceRoleArn", parent: name, max: 10000)
            try self.validate(self.serviceRoleArn, name: "serviceRoleArn", parent: name, pattern: "arn:aws:iam::[0-9]{12}:role/.*")
            try self.subnetIds?.forEach {
                try validate($0, name: "subnetIds[]", parent: name, max: 10000)
                try validate($0, name: "subnetIds[]", parent: name, pattern: "(?s).*")
            }
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case associatePublicIpAddress = "AssociatePublicIpAddress"
            case backupId = "BackupId"
            case backupRetentionCount = "BackupRetentionCount"
            case customCertificate = "CustomCertificate"
            case customDomain = "CustomDomain"
            case customPrivateKey = "CustomPrivateKey"
            case disableAutomatedBackup = "DisableAutomatedBackup"
            case engine = "Engine"
            case engineAttributes = "EngineAttributes"
            case engineModel = "EngineModel"
            case engineVersion = "EngineVersion"
            case instanceProfileArn = "InstanceProfileArn"
            case instanceType = "InstanceType"
            case keyPair = "KeyPair"
            case preferredBackupWindow = "PreferredBackupWindow"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case securityGroupIds = "SecurityGroupIds"
            case serverName = "ServerName"
            case serviceRoleArn = "ServiceRoleArn"
            case subnetIds = "SubnetIds"
            case tags = "Tags"
        }
    }

    public struct CreateServerResponse: AWSDecodableShape {
        /// The server that is created by the request.
        public let server: Server?

        public init(server: Server? = nil) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }

    public struct DeleteBackupRequest: AWSEncodableShape {
        /// The ID of the backup to delete. Run the DescribeBackups command to get a list of backup IDs. Backup IDs are in the format ServerName-yyyyMMddHHmmssSSS.
        public let backupId: String

        public init(backupId: String) {
            self.backupId = backupId
        }

        public func validate(name: String) throws {
            try self.validate(self.backupId, name: "backupId", parent: name, max: 79)
            try self.validate(self.backupId, name: "backupId", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-\\.\\:]*")
        }

        private enum CodingKeys: String, CodingKey {
            case backupId = "BackupId"
        }
    }

    public struct DeleteBackupResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteServerRequest: AWSEncodableShape {
        /// The ID of the server to delete.
        public let serverName: String

        public init(serverName: String) {
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case serverName = "ServerName"
        }
    }

    public struct DeleteServerResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeAccountAttributesRequest: AWSEncodableShape {
        public init() {}
    }

    public struct DescribeAccountAttributesResponse: AWSDecodableShape {
        ///  The attributes that are currently set for the account.
        public let attributes: [AccountAttribute]?

        public init(attributes: [AccountAttribute]? = nil) {
            self.attributes = attributes
        }

        private enum CodingKeys: String, CodingKey {
            case attributes = "Attributes"
        }
    }

    public struct DescribeBackupsRequest: AWSEncodableShape {
        /// Describes a single backup.
        public let backupId: String?
        /// This is not currently implemented for DescribeBackups requests.
        public let maxResults: Int?
        /// This is not currently implemented for DescribeBackups requests.
        public let nextToken: String?
        /// Returns backups for the server with the specified ServerName.
        public let serverName: String?

        public init(backupId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, serverName: String? = nil) {
            self.backupId = backupId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.backupId, name: "backupId", parent: name, max: 79)
            try self.validate(self.backupId, name: "backupId", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-\\.\\:]*")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 10000)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case backupId = "BackupId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serverName = "ServerName"
        }
    }

    public struct DescribeBackupsResponse: AWSDecodableShape {
        /// Contains the response to a DescribeBackups request.
        public let backups: [Backup]?
        /// This is not currently implemented for DescribeBackups requests.
        public let nextToken: String?

        public init(backups: [Backup]? = nil, nextToken: String? = nil) {
            self.backups = backups
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case backups = "Backups"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeEventsRequest: AWSEncodableShape {
        /// To receive a paginated response, use this parameter to specify the maximum number of results to be returned with a single call. If the number of available results exceeds this maximum, the response includes a NextToken value that you can assign to the NextToken request parameter to get the next set of results.
        public let maxResults: Int?
        /// NextToken is a string that is returned in some command responses. It indicates that not all entries have been returned, and that you must run at least one more request to get remaining items. To get remaining results, call DescribeEvents again, and assign the token from the previous results as the value of the nextToken parameter. If there are no more results, the response object's nextToken parameter value is null. Setting a nextToken value that was not returned in your previous results causes an InvalidNextTokenException to occur.
        public let nextToken: String?
        /// The name of the server for which you want to view events.
        public let serverName: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, serverName: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 10000)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serverName = "ServerName"
        }
    }

    public struct DescribeEventsResponse: AWSDecodableShape {
        /// NextToken is a string that is returned in some command responses. It indicates that not all entries have been returned, and that you must run at least one more request to get remaining items. To get remaining results, call DescribeEvents again, and assign the token from the previous results as the value of the nextToken parameter. If there are no more results, the response object's nextToken parameter value is null. Setting a nextToken value that was not returned in your previous results causes an InvalidNextTokenException to occur.
        public let nextToken: String?
        /// Contains the response to a DescribeEvents request.
        public let serverEvents: [ServerEvent]?

        public init(nextToken: String? = nil, serverEvents: [ServerEvent]? = nil) {
            self.nextToken = nextToken
            self.serverEvents = serverEvents
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case serverEvents = "ServerEvents"
        }
    }

    public struct DescribeNodeAssociationStatusRequest: AWSEncodableShape {
        /// The token returned in either the AssociateNodeResponse or the DisassociateNodeResponse.
        public let nodeAssociationStatusToken: String
        /// The name of the server from which to disassociate the node.
        public let serverName: String

        public init(nodeAssociationStatusToken: String, serverName: String) {
            self.nodeAssociationStatusToken = nodeAssociationStatusToken
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.nodeAssociationStatusToken, name: "nodeAssociationStatusToken", parent: name, max: 10000)
            try self.validate(self.nodeAssociationStatusToken, name: "nodeAssociationStatusToken", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case nodeAssociationStatusToken = "NodeAssociationStatusToken"
            case serverName = "ServerName"
        }
    }

    public struct DescribeNodeAssociationStatusResponse: AWSDecodableShape {
        /// Attributes specific to the node association.  In Puppet, the attibute PUPPET_NODE_CERT contains the signed certificate (the result of the CSR).
        public let engineAttributes: [EngineAttribute]?
        /// The status of the association or disassociation request.   Possible values:     SUCCESS: The association or disassociation succeeded.     FAILED: The association or disassociation failed.     IN_PROGRESS: The association or disassociation is still in progress.
        public let nodeAssociationStatus: NodeAssociationStatus?

        public init(engineAttributes: [EngineAttribute]? = nil, nodeAssociationStatus: NodeAssociationStatus? = nil) {
            self.engineAttributes = engineAttributes
            self.nodeAssociationStatus = nodeAssociationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case engineAttributes = "EngineAttributes"
            case nodeAssociationStatus = "NodeAssociationStatus"
        }
    }

    public struct DescribeServersRequest: AWSEncodableShape {
        /// This is not currently implemented for DescribeServers requests.
        public let maxResults: Int?
        /// This is not currently implemented for DescribeServers requests.
        public let nextToken: String?
        /// Describes the server with the specified ServerName.
        public let serverName: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil, serverName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 10000)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serverName = "ServerName"
        }
    }

    public struct DescribeServersResponse: AWSDecodableShape {
        /// This is not currently implemented for DescribeServers requests.
        public let nextToken: String?
        /// Contains the response to a DescribeServers request.  For Chef Automate servers:  If DescribeServersResponse$Servers$EngineAttributes includes  CHEF_MAJOR_UPGRADE_AVAILABLE, you can upgrade the Chef Automate server to Chef Automate 2. To be eligible for upgrade, a server running  Chef Automate 1 must have had at least one successful maintenance run after November 1, 2019.  For Puppet servers:   DescribeServersResponse$Servers$EngineAttributes contains the following two responses:    PUPPET_API_CA_CERT, the PEM-encoded CA certificate that is used by the Puppet API over TCP port number 8140.  The CA certificate is also used to sign node certificates.    PUPPET_API_CRL, a certificate revocation list. The certificate revocation list is for internal  maintenance purposes only. For more information about the Puppet certificate revocation list, see  Man Page: puppet certificate_revocation_list in the Puppet documentation.
        public let servers: [Server]?

        public init(nextToken: String? = nil, servers: [Server]? = nil) {
            self.nextToken = nextToken
            self.servers = servers
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case servers = "Servers"
        }
    }

    public struct DisassociateNodeRequest: AWSEncodableShape {
        /// Engine attributes that are used for disassociating the node. No attributes are required for Puppet.   Attributes required in a DisassociateNode request for Chef     CHEF_ORGANIZATION: The Chef organization with which the node was associated. By default only one organization named default can exist.
        public let engineAttributes: [EngineAttribute]?
        /// The name of the client node.
        public let nodeName: String
        /// The name of the server from which to disassociate the node.
        public let serverName: String

        public init(engineAttributes: [EngineAttribute]? = nil, nodeName: String, serverName: String) {
            self.engineAttributes = engineAttributes
            self.nodeName = nodeName
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.engineAttributes?.forEach {
                try $0.validate(name: "\(name).engineAttributes[]")
            }
            try self.validate(self.nodeName, name: "nodeName", parent: name, max: 10000)
            try self.validate(self.nodeName, name: "nodeName", parent: name, pattern: "^[\\-\\p{Alnum}_:.]+$")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case engineAttributes = "EngineAttributes"
            case nodeName = "NodeName"
            case serverName = "ServerName"
        }
    }

    public struct DisassociateNodeResponse: AWSDecodableShape {
        /// Contains a token which can be passed to the DescribeNodeAssociationStatus API call to get the status of the disassociation request.
        public let nodeAssociationStatusToken: String?

        public init(nodeAssociationStatusToken: String? = nil) {
            self.nodeAssociationStatusToken = nodeAssociationStatusToken
        }

        private enum CodingKeys: String, CodingKey {
            case nodeAssociationStatusToken = "NodeAssociationStatusToken"
        }
    }

    public struct EngineAttribute: AWSEncodableShape & AWSDecodableShape {
        /// The name of the engine attribute.
        public let name: String?
        /// The value of the engine attribute.
        public let value: String?

        public init(name: String? = nil, value: String? = nil) {
            self.name = name
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 10000)
            try self.validate(self.name, name: "name", parent: name, pattern: "(?s).*")
            try self.validate(self.value, name: "value", parent: name, max: 10000)
            try self.validate(self.value, name: "value", parent: name, pattern: "(?s).*")
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case value = "Value"
        }
    }

    public struct ExportServerEngineAttributeRequest: AWSEncodableShape {
        /// The name of the export attribute. Currently, the supported export attribute is Userdata.  This exports a user data script that includes parameters and values provided in the InputAttributes list.
        public let exportAttributeName: String
        /// The list of engine attributes. The list type is EngineAttribute. An EngineAttribute list item  is a pair that includes an attribute name and its value. For the Userdata ExportAttributeName, the following are  supported engine attribute names.    RunList In Chef, a list of roles or recipes that are run in the specified order.  In Puppet, this parameter is ignored.    OrganizationName In Chef, an organization name. AWS OpsWorks for Chef Automate  always creates the organization default. In Puppet, this parameter is ignored.    NodeEnvironment In Chef, a node environment (for example, development, staging, or one-box).  In Puppet, this parameter is ignored.    NodeClientVersion In Chef, the version of the Chef engine (three numbers separated  by dots, such as 13.8.5). If this attribute is empty, OpsWorks for Chef Automate uses the most current version. In Puppet,  this parameter is ignored.
        public let inputAttributes: [EngineAttribute]?
        /// The name of the server from which you are exporting the attribute.
        public let serverName: String

        public init(exportAttributeName: String, inputAttributes: [EngineAttribute]? = nil, serverName: String) {
            self.exportAttributeName = exportAttributeName
            self.inputAttributes = inputAttributes
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.exportAttributeName, name: "exportAttributeName", parent: name, max: 10000)
            try self.validate(self.exportAttributeName, name: "exportAttributeName", parent: name, pattern: "(?s).*")
            try self.inputAttributes?.forEach {
                try $0.validate(name: "\(name).inputAttributes[]")
            }
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case exportAttributeName = "ExportAttributeName"
            case inputAttributes = "InputAttributes"
            case serverName = "ServerName"
        }
    }

    public struct ExportServerEngineAttributeResponse: AWSDecodableShape {
        /// The requested engine attribute pair with attribute name and value.
        public let engineAttribute: EngineAttribute?
        /// The server name used in the request.
        public let serverName: String?

        public init(engineAttribute: EngineAttribute? = nil, serverName: String? = nil) {
            self.engineAttribute = engineAttribute
            self.serverName = serverName
        }

        private enum CodingKeys: String, CodingKey {
            case engineAttribute = "EngineAttribute"
            case serverName = "ServerName"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// To receive a paginated response, use this parameter to specify the maximum number of results to be returned with a single call. If the number of available results exceeds this maximum, the response includes a NextToken value that you can assign to the NextToken request parameter to get the next set of results.
        public let maxResults: Int?
        /// NextToken is a string that is returned in some command responses. It indicates that not all entries have been returned, and that you must run at least one more request to get remaining items. To get remaining results, call ListTagsForResource again, and assign the token from the previous results as the value of the nextToken parameter. If there are no more results, the response object's nextToken parameter value is null. Setting a nextToken value that was not returned in your previous results causes an InvalidNextTokenException to occur.
        public let nextToken: String?
        /// The Amazon Resource Number (ARN) of an AWS OpsWorks for Chef Automate or AWS OpsWorks for Puppet Enterprise server for which you want to show applied tags. For example,  arn:aws:opsworks-cm:us-west-2:123456789012:server/test-owcm-server/EXAMPLE-66b0-4196-8274-d1a2bEXAMPLE.
        public let resourceArn: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceArn: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 10000)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "(?s).*")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:aws.*:opsworks-cm:.*:[0-9]{12}:.*")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A token that you can use as the value of NextToken in subsequent calls to the API to show more results.
        public let nextToken: String?
        /// Tags that have been applied to the resource.
        public let tags: [Tag]?

        public init(nextToken: String? = nil, tags: [Tag]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct RestoreServerRequest: AWSEncodableShape {
        ///  The ID of the backup that you want to use to restore a server.
        public let backupId: String
        ///  The type of instance to restore. Valid values must be specified in the following format: ^([cm][34]|t2).* For example, m5.large. Valid values are m5.large, r5.xlarge, and r5.2xlarge. If you do not specify this parameter, RestoreServer uses the instance type from the specified backup.
        public let instanceType: String?
        ///  The name of the key pair to set on the new EC2 instance. This can be helpful if the administrator no longer has the SSH key.
        public let keyPair: String?
        ///  The name of the server that you want to restore.
        public let serverName: String

        public init(backupId: String, instanceType: String? = nil, keyPair: String? = nil, serverName: String) {
            self.backupId = backupId
            self.instanceType = instanceType
            self.keyPair = keyPair
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.backupId, name: "backupId", parent: name, max: 79)
            try self.validate(self.backupId, name: "backupId", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-\\.\\:]*")
            try self.validate(self.instanceType, name: "instanceType", parent: name, max: 10000)
            try self.validate(self.instanceType, name: "instanceType", parent: name, pattern: "(?s).*")
            try self.validate(self.keyPair, name: "keyPair", parent: name, max: 10000)
            try self.validate(self.keyPair, name: "keyPair", parent: name, pattern: ".*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case backupId = "BackupId"
            case instanceType = "InstanceType"
            case keyPair = "KeyPair"
            case serverName = "ServerName"
        }
    }

    public struct RestoreServerResponse: AWSDecodableShape {
        public let server: Server?

        public init(server: Server? = nil) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }

    public struct Server: AWSDecodableShape {
        /// Associate a public IP address with a server that you are launching.
        public let associatePublicIpAddress: Bool?
        /// The number of automated backups to keep.
        public let backupRetentionCount: Int?
        /// The ARN of the CloudFormation stack that was used to create the server.
        public let cloudFormationStackArn: String?
        /// Time stamp of server creation. Example 2016-07-29T13:38:47.520Z
        public let createdAt: Date?
        /// An optional public endpoint of a server, such as https://aws.my-company.com.  You cannot access the server by using the Endpoint value if the server has a CustomDomain specified.
        public let customDomain: String?
        /// Disables automated backups. The number of stored backups is dependent on the value of PreferredBackupCount.
        public let disableAutomatedBackup: Bool?
        ///  A DNS name that can be used to access the engine. Example: myserver-asdfghjkl.us-east-1.opsworks.io.  You cannot access the server by using the Endpoint value if the server has a CustomDomain specified.
        public let endpoint: String?
        /// The engine type of the server. Valid values in this release include ChefAutomate and Puppet.
        public let engine: String?
        /// The response of a createServer() request returns the master credential to access the server in EngineAttributes. These credentials are not stored by AWS OpsWorks CM; they are returned only as part of the result of createServer().   Attributes returned in a createServer response for Chef     CHEF_AUTOMATE_PIVOTAL_KEY: A base64-encoded RSA private key that is generated by AWS OpsWorks for Chef Automate. This private key is required to access the Chef API.    CHEF_STARTER_KIT: A base64-encoded ZIP file. The ZIP file contains a Chef starter kit, which includes a README, a configuration file, and the required RSA private key. Save this file, unzip it, and then change to the directory where you've unzipped the file contents. From this directory, you can run Knife commands.    Attributes returned in a createServer response for Puppet     PUPPET_STARTER_KIT: A base64-encoded ZIP file. The ZIP file contains a Puppet starter kit, including a README and a required private key. Save this file, unzip it, and then change to the directory where you've unzipped the file contents.    PUPPET_ADMIN_PASSWORD: An administrator password that you can use to sign in to the Puppet Enterprise console after the server is online.
        public let engineAttributes: [EngineAttribute]?
        /// The engine model of the server. Valid values in this release include Monolithic for Puppet and Single for Chef.
        public let engineModel: String?
        /// The engine version of the server. For a Chef server, the valid value for EngineVersion is  currently 2. For a Puppet server, specify either 2019 or 2017.
        public let engineVersion: String?
        /// The instance profile ARN of the server.
        public let instanceProfileArn: String?
        ///  The instance type for the server, as specified in the CloudFormation stack. This might not be the same instance type that is shown in the EC2 console.
        public let instanceType: String?
        /// The key pair associated with the server.
        public let keyPair: String?
        /// The status of the most recent server maintenance run. Shows SUCCESS or FAILED.
        public let maintenanceStatus: MaintenanceStatus?
        /// The preferred backup period specified for the server.
        public let preferredBackupWindow: String?
        /// The preferred maintenance period specified for the server.
        public let preferredMaintenanceWindow: String?
        ///  The security group IDs for the server, as specified in the CloudFormation stack. These might not be the same security groups that are shown in the EC2 console.
        public let securityGroupIds: [String]?
        /// The ARN of the server.
        public let serverArn: String?
        /// The name of the server.
        public let serverName: String?
        /// The service role ARN used to create the server.
        public let serviceRoleArn: String?
        ///  The server's status. This field displays the states of actions in progress, such as creating, running, or backing up the server, as well as the server's health state.
        public let status: ServerStatus?
        ///  Depending on the server status, this field has either a human-readable message (such as a create or backup error), or an escaped block of JSON (used for health check results).
        public let statusReason: String?
        ///  The subnet IDs specified in a CreateServer request.
        public let subnetIds: [String]?

        public init(associatePublicIpAddress: Bool? = nil, backupRetentionCount: Int? = nil, cloudFormationStackArn: String? = nil, createdAt: Date? = nil, customDomain: String? = nil, disableAutomatedBackup: Bool? = nil, endpoint: String? = nil, engine: String? = nil, engineAttributes: [EngineAttribute]? = nil, engineModel: String? = nil, engineVersion: String? = nil, instanceProfileArn: String? = nil, instanceType: String? = nil, keyPair: String? = nil, maintenanceStatus: MaintenanceStatus? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, securityGroupIds: [String]? = nil, serverArn: String? = nil, serverName: String? = nil, serviceRoleArn: String? = nil, status: ServerStatus? = nil, statusReason: String? = nil, subnetIds: [String]? = nil) {
            self.associatePublicIpAddress = associatePublicIpAddress
            self.backupRetentionCount = backupRetentionCount
            self.cloudFormationStackArn = cloudFormationStackArn
            self.createdAt = createdAt
            self.customDomain = customDomain
            self.disableAutomatedBackup = disableAutomatedBackup
            self.endpoint = endpoint
            self.engine = engine
            self.engineAttributes = engineAttributes
            self.engineModel = engineModel
            self.engineVersion = engineVersion
            self.instanceProfileArn = instanceProfileArn
            self.instanceType = instanceType
            self.keyPair = keyPair
            self.maintenanceStatus = maintenanceStatus
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.securityGroupIds = securityGroupIds
            self.serverArn = serverArn
            self.serverName = serverName
            self.serviceRoleArn = serviceRoleArn
            self.status = status
            self.statusReason = statusReason
            self.subnetIds = subnetIds
        }

        private enum CodingKeys: String, CodingKey {
            case associatePublicIpAddress = "AssociatePublicIpAddress"
            case backupRetentionCount = "BackupRetentionCount"
            case cloudFormationStackArn = "CloudFormationStackArn"
            case createdAt = "CreatedAt"
            case customDomain = "CustomDomain"
            case disableAutomatedBackup = "DisableAutomatedBackup"
            case endpoint = "Endpoint"
            case engine = "Engine"
            case engineAttributes = "EngineAttributes"
            case engineModel = "EngineModel"
            case engineVersion = "EngineVersion"
            case instanceProfileArn = "InstanceProfileArn"
            case instanceType = "InstanceType"
            case keyPair = "KeyPair"
            case maintenanceStatus = "MaintenanceStatus"
            case preferredBackupWindow = "PreferredBackupWindow"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case securityGroupIds = "SecurityGroupIds"
            case serverArn = "ServerArn"
            case serverName = "ServerName"
            case serviceRoleArn = "ServiceRoleArn"
            case status = "Status"
            case statusReason = "StatusReason"
            case subnetIds = "SubnetIds"
        }
    }

    public struct ServerEvent: AWSDecodableShape {
        /// The time when the event occurred.
        public let createdAt: Date?
        /// The Amazon S3 URL of the event's log file.
        public let logUrl: String?
        /// A human-readable informational or status message.
        public let message: String?
        /// The name of the server on or for which the event occurred.
        public let serverName: String?

        public init(createdAt: Date? = nil, logUrl: String? = nil, message: String? = nil, serverName: String? = nil) {
            self.createdAt = createdAt
            self.logUrl = logUrl
            self.message = message
            self.serverName = serverName
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case logUrl = "LogUrl"
            case message = "Message"
            case serverName = "ServerName"
        }
    }

    public struct StartMaintenanceRequest: AWSEncodableShape {
        /// Engine attributes that are specific to the server on which you want to run maintenance.  Attributes accepted in a StartMaintenance request for Chef     CHEF_MAJOR_UPGRADE: If a Chef Automate server is eligible for upgrade to Chef Automate 2,  add this engine attribute to a StartMaintenance request and set the value to true to upgrade the server to Chef Automate 2. For more information, see  Upgrade an AWS OpsWorks for Chef Automate Server to Chef Automate 2.
        public let engineAttributes: [EngineAttribute]?
        /// The name of the server on which to run maintenance.
        public let serverName: String

        public init(engineAttributes: [EngineAttribute]? = nil, serverName: String) {
            self.engineAttributes = engineAttributes
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.engineAttributes?.forEach {
                try $0.validate(name: "\(name).engineAttributes[]")
            }
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case engineAttributes = "EngineAttributes"
            case serverName = "ServerName"
        }
    }

    public struct StartMaintenanceResponse: AWSDecodableShape {
        /// Contains the response to a StartMaintenance request.
        public let server: Server?

        public init(server: Server? = nil) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// A tag key, such as Stage or Name. A tag key cannot be empty. The key can be a maximum of 127 characters,  and can contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /
        public let key: String
        /// An optional tag value, such as Production or test-owcm-server. The value can be a maximum of 255 characters,  and contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Number (ARN) of a resource to which you want to apply tags. For example,  arn:aws:opsworks-cm:us-west-2:123456789012:server/test-owcm-server/EXAMPLE-66b0-4196-8274-d1a2bEXAMPLE.
        public let resourceArn: String
        /// A map that contains tag keys and tag values to attach to AWS OpsWorks-CM servers or backups.   The key cannot be empty.   The key can be a maximum of 127 characters, and can contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /    The value can be a maximum 255 characters, and contain only Unicode letters, numbers, or separators, or the following special characters: + - = . _ : /    Leading and trailing white spaces are trimmed from both the key and value.   A maximum of 50 user-applied tags is allowed for any AWS OpsWorks-CM server or backup.
        public let tags: [Tag]

        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:aws.*:opsworks-cm:.*:[0-9]{12}:.*")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Number (ARN) of a resource from which you want to remove tags. For example,  arn:aws:opsworks-cm:us-west-2:123456789012:server/test-owcm-server/EXAMPLE-66b0-4196-8274-d1a2bEXAMPLE.
        public let resourceArn: String
        /// The keys of tags that you want to remove.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:aws.*:opsworks-cm:.*:[0-9]{12}:.*")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateServerEngineAttributesRequest: AWSEncodableShape {
        /// The name of the engine attribute to update.
        public let attributeName: String
        /// The value to set for the attribute.
        public let attributeValue: String?
        /// The name of the server to update.
        public let serverName: String

        public init(attributeName: String, attributeValue: String? = nil, serverName: String) {
            self.attributeName = attributeName
            self.attributeValue = attributeValue
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.attributeName, name: "attributeName", parent: name, max: 64)
            try self.validate(self.attributeName, name: "attributeName", parent: name, min: 1)
            try self.validate(self.attributeName, name: "attributeName", parent: name, pattern: "[A-Z][A-Z0-9_]*")
            try self.validate(self.attributeValue, name: "attributeValue", parent: name, max: 10000)
            try self.validate(self.attributeValue, name: "attributeValue", parent: name, pattern: "(?s).*")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case attributeName = "AttributeName"
            case attributeValue = "AttributeValue"
            case serverName = "ServerName"
        }
    }

    public struct UpdateServerEngineAttributesResponse: AWSDecodableShape {
        /// Contains the response to an UpdateServerEngineAttributes request.
        public let server: Server?

        public init(server: Server? = nil) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }

    public struct UpdateServerRequest: AWSEncodableShape {
        /// Sets the number of automated backups that you want to keep.
        public let backupRetentionCount: Int?
        /// Setting DisableAutomatedBackup to true disables automated or scheduled backups. Automated backups are enabled by default.
        public let disableAutomatedBackup: Bool?
        public let preferredBackupWindow: String?
        public let preferredMaintenanceWindow: String?
        /// The name of the server to update.
        public let serverName: String

        public init(backupRetentionCount: Int? = nil, disableAutomatedBackup: Bool? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, serverName: String) {
            self.backupRetentionCount = backupRetentionCount
            self.disableAutomatedBackup = disableAutomatedBackup
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.serverName = serverName
        }

        public func validate(name: String) throws {
            try self.validate(self.preferredBackupWindow, name: "preferredBackupWindow", parent: name, max: 10000)
            try self.validate(self.preferredBackupWindow, name: "preferredBackupWindow", parent: name, pattern: "^((Mon|Tue|Wed|Thu|Fri|Sat|Sun):)?([0-1][0-9]|2[0-3]):[0-5][0-9]$")
            try self.validate(self.preferredMaintenanceWindow, name: "preferredMaintenanceWindow", parent: name, max: 10000)
            try self.validate(self.preferredMaintenanceWindow, name: "preferredMaintenanceWindow", parent: name, pattern: "^((Mon|Tue|Wed|Thu|Fri|Sat|Sun):)?([0-1][0-9]|2[0-3]):[0-5][0-9]$")
            try self.validate(self.serverName, name: "serverName", parent: name, max: 40)
            try self.validate(self.serverName, name: "serverName", parent: name, min: 1)
            try self.validate(self.serverName, name: "serverName", parent: name, pattern: "[a-zA-Z][a-zA-Z0-9\\-]*")
        }

        private enum CodingKeys: String, CodingKey {
            case backupRetentionCount = "BackupRetentionCount"
            case disableAutomatedBackup = "DisableAutomatedBackup"
            case preferredBackupWindow = "PreferredBackupWindow"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case serverName = "ServerName"
        }
    }

    public struct UpdateServerResponse: AWSDecodableShape {
        /// Contains the response to a UpdateServer request.
        public let server: Server?

        public init(server: Server? = nil) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }
}

// MARK: - Errors

/// Error enum for OpsWorksCM
public struct OpsWorksCMErrorType: AWSErrorType {
    enum Code: String {
        case invalidNextTokenException = "InvalidNextTokenException"
        case invalidStateException = "InvalidStateException"
        case limitExceededException = "LimitExceededException"
        case resourceAlreadyExistsException = "ResourceAlreadyExistsException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize OpsWorksCM
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// This occurs when the provided nextToken is not valid.
    public static var invalidNextTokenException: Self { .init(.invalidNextTokenException) }
    /// The resource is in a state that does not allow you to perform a specified action.
    public static var invalidStateException: Self { .init(.invalidStateException) }
    /// The limit of servers or backups has been reached.
    public static var limitExceededException: Self { .init(.limitExceededException) }
    /// The requested resource cannot be created because it already exists.
    public static var resourceAlreadyExistsException: Self { .init(.resourceAlreadyExistsException) }
    /// The requested resource does not exist, or access was denied.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// One or more of the provided request parameters are not valid.
    public static var validationException: Self { .init(.validationException) }
}

extension OpsWorksCMErrorType: Equatable {
    public static func == (lhs: OpsWorksCMErrorType, rhs: OpsWorksCMErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension OpsWorksCMErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
